package cn.com.jrr.core.aspect;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import cn.com.jrr.core.anotation.SystemControllerLog;
import cn.com.jrr.core.anotation.SystemServiceLog;

@SuppressWarnings("all")
@Aspect
@Component
public class TestAspect {
    //Service层切点
    @Pointcut("@annotation(cn.com.jrr.core.anotation.SystemServiceLog)")
    public  void serviceAspect() {}

    //Controller层切点
    @Pointcut("@annotation(cn.com.jrr.core.anotation.SystemControllerLog)")
    public  void controllerAspect() {}


    /*@Before("execution(* cn.com.jrr.service.*.*(..))")
    public void before(JoinPoint joinPoint){
        System.out.println("---------before "+joinPoint+" --------");
    }*/
    @Before("controllerAspect()")
    public void doBefore(JoinPoint joinPoint){
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        HttpSession session = request.getSession();
        //请求的IP
        String ip = request.getRemoteAddr();
        try {
            System.out.println("=====前置通知开始=====");
            System.out.println("请求方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));
            System.out.println("方法描述:" + getControllerMethodDescription(joinPoint));
            System.out.println("请求IP:" + ip);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }




    @After("execution(* cn.com.jrr.service.*.*(..))")
    public void After(JoinPoint joinPoint){
        System.out.println("---"+joinPoint+"执行完毕！");
    }




    /**
     * 获取注解中对方法的描述信息 用于Controller层注解
     *
     * @param joinPoint 切点
     * @return 方法描述
     * @throws Exception
     */
    public  static String getControllerMethodDescription(JoinPoint joinPoint)  throws Exception {
        String targetName = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        Object[] arguments = joinPoint.getArgs();

        Class targetClass = Class.forName(targetName);
        Method[] methods = targetClass.getMethods();
        String description = "";
        for (Method method : methods) {
            //排除不同类中同名方法
            if (method.getName().equals(methodName)) {
                //获取方法的所有参数类型
                Class[] clazzs = method.getParameterTypes();
                //排除同名不同参数方法
                if (clazzs.length == arguments.length) {
                    description = method.getAnnotation(SystemControllerLog. class).description();
                    break;
                }
            }
        }
        return description;
    }



    /**
     * 获取注解中对方法的描述信息 用于service层注解
     *
     * @param joinPoint 切点
     * @return 方法描述
     * @throws Exception
     */
    public  static String getServiceMthodDescription(JoinPoint joinPoint)
            throws Exception {
        String targetName = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        Object[] arguments = joinPoint.getArgs();
        Class targetClass = Class.forName(targetName);
        Method[] methods = targetClass.getMethods();
        String description = "";
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                Class[] clazzs = method.getParameterTypes();
                if (clazzs.length == arguments.length) {
                    description = method.getAnnotation(SystemServiceLog. class).description();
                    break;
                }
            }
        }
        return description;
    }
}
